home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / diskBoot.OpenProm / fsIndex.c < prev    next >
C/C++ Source or Header  |  1991-01-14  |  6KB  |  244 lines

  1. /* 
  2.  * fsIndex.c --
  3.  *
  4.  *    Routines to allow moving through a files block pointers.
  5.  *
  6.  * Copyright 1986 Regents of the University of California
  7.  * All rights reserved.
  8.  */
  9.  
  10. #ifdef notdef
  11. static char rcsid[] = "$Header: /sprite/src/boot/scsiDiskBoot/RCS/fsIndex.c,v 1.6 89/06/16 08:30:08 brent Exp $ SPRITE (Berkeley)";
  12. #endif not lint
  13.  
  14. #include "sprite.h"
  15. #include "fsBoot.h"
  16. #include "ofs.h"
  17. #include "byte.h"
  18.  
  19. char    firstBlockBuffer[FS_BLOCK_SIZE];
  20. char    secondBlockBuffer[FS_BLOCK_SIZE];
  21.  
  22.  
  23. /*
  24.  *----------------------------------------------------------------------
  25.  *
  26.  * MakePtrAccessible --
  27.  *
  28.  *    Make the block pointer in the file descriptor accessible.  This
  29.  *    may entail reading in indirect blocks and locking them down in the
  30.  *    cache.
  31.  *
  32.  * Results:
  33.  *    None.
  34.  *
  35.  * Side effects:
  36.  *    Indirect blocks are locked down in the cache.
  37.  *
  38.  *----------------------------------------------------------------------
  39.  */
  40.  
  41. static ReturnStatus
  42. MakePtrAccessible(handlePtr, indexInfoPtr, descPtr)
  43.     register    Fsio_FileIOHandle     *handlePtr;
  44.     register    BlockIndexInfo      *indexInfoPtr;
  45.     register    Fsdm_FileDescriptor *descPtr;
  46. {
  47.     register     int          *blockAddrPtr;
  48.  
  49.     /* 
  50.      * Read in the first block.
  51.      */
  52.  
  53.     if (indexInfoPtr->firstBlockNil) {
  54.     FsDeviceBlockIO(FS_READ, &fsDevice,
  55.               descPtr->indirect[indexInfoPtr->indexType],
  56.               FS_FRAGMENTS_PER_BLOCK, firstBlockBuffer);
  57.     }
  58.  
  59.     blockAddrPtr = 
  60.     (int *) (firstBlockBuffer + sizeof(int) * indexInfoPtr->firstIndex);
  61.  
  62.     if (indexInfoPtr->indexType == FSDM_INDIRECT) {
  63.     indexInfoPtr->blockAddrPtr = blockAddrPtr;
  64.     return(SUCCESS);
  65.     }
  66.  
  67.     /* 
  68.      * Get the second level block.
  69.      */
  70.  
  71.     FsDeviceBlockIO(FS_READ, &fsDevice, *blockAddrPtr,
  72.                FS_FRAGMENTS_PER_BLOCK, secondBlockBuffer);
  73.     indexInfoPtr->blockAddrPtr = 
  74.     (int *) (secondBlockBuffer + sizeof(int) * indexInfoPtr->secondIndex);
  75.  
  76.     return(SUCCESS);
  77. }
  78.  
  79.  
  80. /*
  81.  *----------------------------------------------------------------------
  82.  *
  83.  * FsGetFirstIndex --
  84.  *
  85.  *    Initialize the index structure.  This will set up the index info
  86.  *    structure so that it contains a pointer to the desired block pointer.
  87.  *
  88.  * Results:
  89.  *    A status indicating whether there was sufficient space to allocate
  90.  *    indirect blocks.
  91.  *
  92.  * Side effects:
  93.  *    The index structure is initialized.
  94.  *
  95.  *----------------------------------------------------------------------
  96.  */
  97.  
  98. ReturnStatus
  99. FsGetFirstIndex(handlePtr, blockNum, indexInfoPtr)
  100.     register Fsio_FileIOHandle        *handlePtr;    /* Handle for file that are 
  101.                           indexing. */
  102.     register int        blockNum;      /* Where to start indexing. */
  103.     register BlockIndexInfo *indexInfoPtr; /* Index structure to initialize.*/
  104. {
  105.     register Fsdm_FileDescriptor *descPtr;
  106.     register int          indirectBlock;
  107.  
  108.     descPtr = handlePtr->descPtr;
  109.     indexInfoPtr->firstBlockNil = TRUE;
  110.     indexInfoPtr->blockNum = blockNum;
  111.  
  112.     if (blockNum < FSDM_NUM_DIRECT_BLOCKS) {
  113.     /*
  114.      * This is a direct block.
  115.      */
  116.     indexInfoPtr->indexType = FSDM_DIRECT;
  117.     indexInfoPtr->blockAddrPtr = &descPtr->direct[blockNum];
  118.     return(SUCCESS);
  119.     }
  120.  
  121.     /*
  122.      * Is an indirect block.
  123.      */
  124.  
  125.     blockNum -= FSDM_NUM_DIRECT_BLOCKS;
  126.     indirectBlock = blockNum / FSDM_INDICES_PER_BLOCK;
  127.     if (indirectBlock == 0) {
  128.     /*
  129.      * This is a singly indirect block.
  130.      */
  131.     indexInfoPtr->indexType = FSDM_INDIRECT;
  132.     indexInfoPtr->firstIndex = blockNum;
  133.     } else {
  134.     /*
  135.      * This a doubly indirect block.
  136.      */
  137.     indexInfoPtr->indexType = FSDM_DBL_INDIRECT;
  138.     indexInfoPtr->firstIndex = indirectBlock - 1;
  139.     indexInfoPtr->secondIndex = blockNum -
  140.                     indirectBlock * FSDM_INDICES_PER_BLOCK;
  141.     }
  142.  
  143.     /*
  144.      * Finish off by making the block pointer accessible.  This may include
  145.      * reading indirect blocks into the cache.
  146.      */
  147.  
  148.     return(MakePtrAccessible(handlePtr, indexInfoPtr, descPtr));
  149. }
  150.  
  151.  
  152. /*
  153.  *----------------------------------------------------------------------
  154.  *
  155.  * FsGetNextIndex --
  156.  *
  157.  *    Put the correct pointers in the index structure to access the
  158.  *    block after the current block.
  159.  *
  160.  * Results:
  161.  *    A status indicating whether there was sufficient space to allocate
  162.  *    indirect blocks if they were needed.
  163.  *
  164.  * Side effects:
  165.  *    The allocation structure is modified.
  166.  *
  167.  *----------------------------------------------------------------------
  168.  */
  169.  
  170. ReturnStatus
  171. FsGetNextIndex(handlePtr, indexInfoPtr)
  172.     register Fsio_FileIOHandle       *handlePtr;    /* Handle for file that is being
  173.                           indexed. */
  174.     register BlockIndexInfo *indexInfoPtr; /* Index structure to set up. */
  175. {
  176.     register Boolean          accessible = FALSE;
  177.     register Fsdm_FileDescriptor *descPtr;
  178.  
  179.     descPtr = handlePtr->descPtr;
  180.     indexInfoPtr->blockNum++;
  181.  
  182.     /*
  183.      * Determine whether we are now in direct, indirect or doubly indirect
  184.      * blocks.
  185.      */
  186.  
  187.     switch (indexInfoPtr->indexType) {
  188.     case FSDM_DIRECT:
  189.         if (indexInfoPtr->blockNum < FSDM_NUM_DIRECT_BLOCKS) {
  190.         /*
  191.          * Still in the direct blocks.
  192.          */
  193.         indexInfoPtr->blockAddrPtr++;
  194.         accessible = TRUE;
  195.         } else {
  196.         /*
  197.          * Moved into indirect blocks.
  198.          */
  199.         indexInfoPtr->indexType = FSDM_INDIRECT;
  200.         indexInfoPtr->firstIndex = 0;
  201.         }
  202.         break;
  203.     case FSDM_INDIRECT:
  204.         if (indexInfoPtr->blockNum < 
  205.             FSDM_NUM_DIRECT_BLOCKS + FSDM_INDICES_PER_BLOCK) {
  206.         /*
  207.          * Still in singly indirect blocks.
  208.          */
  209.         indexInfoPtr->blockAddrPtr++;
  210.         accessible = TRUE;
  211.         break;
  212.        } else {
  213.         /*
  214.          * Moved into doubly indirect blocks.
  215.          */
  216.         indexInfoPtr->firstIndex = 0;
  217.         indexInfoPtr->secondIndex = 0;
  218.         indexInfoPtr->indexType = FSDM_DBL_INDIRECT;
  219.         indexInfoPtr->firstBlockNil = TRUE;
  220.         }
  221.         break;
  222.     case FSDM_DBL_INDIRECT:
  223.         indexInfoPtr->secondIndex++;
  224.         if (indexInfoPtr->secondIndex == FSDM_INDICES_PER_BLOCK) {
  225.         indexInfoPtr->firstIndex++;
  226.         indexInfoPtr->secondIndex = 0;
  227.         } else {
  228.         indexInfoPtr->blockAddrPtr++;
  229.         accessible = TRUE;
  230.         }
  231.         break;
  232.     }
  233.  
  234.     /*
  235.      * Make the block pointers accessible if necessary.
  236.      */
  237.  
  238.     if (!accessible) {
  239.     return(MakePtrAccessible(handlePtr, indexInfoPtr, descPtr));
  240.     } else {
  241.     return(SUCCESS);
  242.     }
  243. }
  244.